/*
 * Sylvain BERTRAND <digital.ragnarok@gmail.com>
 * code protected by GNU GPL v3
 */
#include <string.h>
#include <X11/Xlib.h>
#include <glib.h>
#include "../toolkit/display.h"
#include "window.h"
#include "misc.h"
#include "wm.h"
#include "stacking.h"
#include "focus_cycle.h"
#include "focus_cycle_indicator.h"
#include "event.h"
#include "geom.h"
#include "frame.h"
#include "client.h"
#define FOCUS_INDICATOR_WIDTH 20
static struct {
	struct wm_internal_window top;
	struct wm_internal_window left;
	struct wm_internal_window right;
	struct wm_internal_window bottom;
	XColor c;
} focus_indicator;
static gboolean visible;

static Window create_window(XColor *c)
{
	XSetWindowAttributes attr;

	attr.override_redirect = True;
	attr.background_pixel = c->pixel;
	
	return XCreateWindow(t_display, DefaultRootWindow(t_display), 0, 0, 1, 1, 0,
							DefaultDepth(t_display, DefaultScreen(t_display)), InputOutput,
							DefaultVisual(t_display, DefaultScreen(t_display)), CWOverrideRedirect | CWBackPixel, &attr);
}

void focus_cycle_indicator_startup(void)
{
	focus_indicator.c.red = 0xffff;
	focus_indicator.c.flags = DoRed;

	XAllocColor(t_display, DefaultColormap(t_display, DefaultScreen(t_display)), &focus_indicator.c);

	visible = FALSE;
	focus_indicator.top.type = WM_WINDOW_CLASS_INTERNAL;
	focus_indicator.left.type = WM_WINDOW_CLASS_INTERNAL;
	focus_indicator.right.type = WM_WINDOW_CLASS_INTERNAL;
	focus_indicator.bottom.type = WM_WINDOW_CLASS_INTERNAL;
	focus_indicator.top.window = create_window(&focus_indicator.c);
	focus_indicator.left.window = create_window(&focus_indicator.c);
	focus_indicator.right.window = create_window(&focus_indicator.c);
	focus_indicator.bottom.window = create_window(&focus_indicator.c);
	stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.top));
	stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.left));
	stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.right));
	stacking_add(INTERNAL_AS_WINDOW(&focus_indicator.bottom));
	window_add(&focus_indicator.top.window, INTERNAL_AS_WINDOW(&focus_indicator.top));
	window_add(&focus_indicator.left.window, INTERNAL_AS_WINDOW(&focus_indicator.left));
	window_add(&focus_indicator.right.window, INTERNAL_AS_WINDOW(&focus_indicator.right));
	window_add(&focus_indicator.bottom.window, INTERNAL_AS_WINDOW(&focus_indicator.bottom));
}

void focus_cycle_indicator_shutdown(void)
{
	window_remove(focus_indicator.top.window);
	window_remove(focus_indicator.left.window);
	window_remove(focus_indicator.right.window);
	window_remove(focus_indicator.bottom.window);
	stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.top));
	stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.left));
	stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.right));
	stacking_remove(INTERNAL_AS_WINDOW(&focus_indicator.bottom));
	XDestroyWindow(t_display, focus_indicator.top.window);
	XDestroyWindow(t_display, focus_indicator.left.window);
	XDestroyWindow(t_display, focus_indicator.right.window);
	XDestroyWindow(t_display, focus_indicator.bottom.window);

	XFreeColors(t_display, DefaultColormap(t_display, DefaultScreen(t_display)), &focus_indicator.c.pixel, 1, 0);
}

void focus_cycle_update_indicator(struct wm_client *c)
{
	if(visible)
		focus_cycle_draw_indicator(c);
}

void focus_cycle_draw_indicator(struct wm_client *c)
{
	if(!c && visible) {
		gulong ignore_start;
		ignore_start = event_start_ignore_all_enters();
		XUnmapWindow(t_display, focus_indicator.top.window);
		XUnmapWindow(t_display, focus_indicator.left.window);
		XUnmapWindow(t_display, focus_indicator.right.window);
		XUnmapWindow(t_display, focus_indicator.bottom.window);
		event_end_ignore_all_enters(ignore_start);
		visible = FALSE;
	} else if(c) {
		gint x, y, w, h;
		gint wt, wl, wr, wb;
		gulong ignore_start;

		wt = wl = wr = wb = FOCUS_INDICATOR_WIDTH;
		x = c->frame->area.x;
		y = c->frame->area.y;
		w = c->frame->area.width;
		h = wt;
		ignore_start = event_start_ignore_all_enters();
		XMoveResizeWindow(t_display, focus_indicator.top.window, x, y, w, h);
		x = c->frame->area.x;
		y = c->frame->area.y;
		w = wl;
		h = c->frame->area.height;
		XMoveResizeWindow(t_display, focus_indicator.left.window, x, y, w, h);
		x = c->frame->area.x + c->frame->area.width - wr;
		y = c->frame->area.y;
		w = wr;
		h = c->frame->area.height;
		XMoveResizeWindow(t_display, focus_indicator.right.window, x, y, w, h);
		x = c->frame->area.x;
		y = c->frame->area.y + c->frame->area.height - wb;
		w = c->frame->area.width;
		h = wb;
		XMoveResizeWindow(t_display, focus_indicator.bottom.window, x, y, w, h);
		XMapWindow(t_display, focus_indicator.top.window);
		XMapWindow(t_display, focus_indicator.left.window);
		XMapWindow(t_display, focus_indicator.right.window);
		XMapWindow(t_display, focus_indicator.bottom.window);
		event_end_ignore_all_enters(ignore_start);
		visible = TRUE;
	}
}
